﻿''' <summary>
''' データベースコネクションを管理するクラス
''' </summary>
''' <remarks></remarks>
Public Class DB

    ''' <summary>
    ''' コンストラクタ
    ''' </summary>
    ''' <param name="cnActivator"></param>
    ''' <param name="connection"></param>
    ''' <param name="paramPrefix"></param>
    ''' <remarks></remarks>
    Public Sub New(cnActivator As Func(Of IDbConnection), connection As String, paramPrefix As String)
        Me.ConnectionActivator = cnActivator
        Me.ConnectionString = connection
        Me.ParameterPrefix = paramPrefix
    End Sub

    ''' <summary>
    ''' コネクションアクティベータ
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Property ConnectionActivator As Func(Of IDbConnection)

    ''' <summary>
    ''' 接続文字列
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Friend Property ConnectionString As String

    ''' <summary>
    ''' パラメータ接頭語
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Property ParameterPrefix As String

    ''' <summary>
    ''' 接続します
    ''' </summary>
    ''' <param name="callback">メインロジックへのコールバック</param>
    ''' <remarks></remarks>
    Public Sub Connect(callback As Action(Of Loader))
        If callback Is Nothing Then Throw New ArgumentNullException("callback")

        Using cn As IDbConnection = Me.ConnectionActivator.Invoke
            cn.ConnectionString = Me.ConnectionString
            cn.Open()

            Dim r As New Loader(cn, Me.ParameterPrefix)
            callback.Invoke(r)
        End Using
    End Sub

    ''' <summary>
    ''' トランザクションします
    ''' </summary>
    ''' <param name="callback">メインロジックへのコールバック</param>
    ''' <remarks></remarks>
    Public Sub Transact(callback As Action(Of Saver))
        If callback Is Nothing Then Throw New ArgumentNullException("callback")

        Using cn = Me.ConnectionActivator.Invoke
            cn.ConnectionString = Me.ConnectionString
            cn.Open()

            Using trn = cn.BeginTransaction
                Try
                    Dim r = Saver.Create(trn, Me.ParameterPrefix)
                    callback.Invoke(r)
                    trn.Commit()
                Catch ex As Exception
                    trn.Rollback()
                    Throw
                End Try
            End Using
        End Using
    End Sub
End Class
